/*
web socket protocol
*/
package wsptc

import (
	"encoding/binary"
	"reflect"
	"strings"

	"gitee.com/MikeDDD/gu/logs"
	"google.golang.org/protobuf/proto"
)

func Hash(name string) uint32 {
	arrByte := []byte(name)
	var nHash uint32 = 1315423911
	for _, c := range arrByte {
		nHash ^= (nHash << 5) + uint32(c) + (nHash >> 2)
	}
	return nHash & 0x7FFFFFFF
}

func Equal(s1 []byte, s2 []byte) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i := 0; i < len(s1); i++ {
		if s1[i] != s2[i] {
			return false
		}
	}
	return true
}

func MessageId(message any) []byte {
	msgType := reflect.TypeOf(message)
	arrMsgNameRes := strings.Split(msgType.String(), ".")  // s := strings.Split("a.b.c.d.c2srequest",".")
	hashValue := Hash(arrMsgNameRes[len(arrMsgNameRes)-1]) // hash("c2srequest")
	hashByte := make([]byte, 4)
	binary.BigEndian.PutUint32(hashByte, hashValue)
	return hashByte
}

func Encode(message proto.Message) []byte {
	binaryData, err := proto.Marshal(message)
	if err != nil {
		logs.Error(err)
		return nil
	}

	name := reflect.TypeOf(message).Elem().Name()
	nameHash := Hash(name)

	output := make([]byte, 4, 4)
	binary.BigEndian.PutUint32(output, nameHash)

	output = append(output, binaryData...)

	return output
}

func Decode(message []byte) (uint32, []byte, bool) {
	if len(message) < 4 {
		return 0, nil, false
	}

	return binary.BigEndian.Uint32(message[:4]), message[4:], true
}
